/*
 * PhotonRTOS础光实时操作系统 -- os_application测试代码
 *
 * Copyright (C) 2023 国科础石(重庆)软件有限公司
 *
 * 作者: Lin Yang <s-yanglin@kernelsoft.com>
 *
 * License terms: GNU General Public License (GPL) version 3
 *
 */

#include "../utest.h"

#if (defined(AUTOSAR_OS_APPLICATION) || defined(AUTOSAR_MULTICORE))
/**
 * [SWS_Os_00514] ⌈ GetApplicationID()的可用性：在可扩展性等级 3 和 4 以及多核系统中可用。 ⌋ ( )
 */
TEST(GetApplicationID)
{
	VAR(ApplicationType, AUTOMATIC) app_id = GetApplicationID();
	P2VAR(struct process_desc, AUTOMATIC, OS_APPL_DATA) pro_desc = current_proc_info();

	/**
	 * [SWS_Os_00261] ⌈ GetApplicationID()应返回配置执行任务/ISR/hook 的应用程序标识符。 ⌋ ( )
	 * [SWS_Os_00262] ⌈如果没有 OS-Application 正在运行，
	 *  GetApplicationID()应返回INVALID_OSAPPLICATION ⌋ ( )
	 */
	if (pro_desc->object.app_id >= INVALID_OSAPPLICATION) {
		ASSERT_EQ(app_id, INVALID_OSAPPLICATION);
	} else {
		ASSERT_EQ(app_id, pro_desc->object.app_id);
	}
}
#endif /* (defined(AUTOSAR_OS_APPLICATION) || defined(AUTOSAR_MULTICORE)) */

#if defined(AUTOSAR_OS_APPLICATION)
/**
 * [SWS_Os_00800] ⌈ GetCurrentApplicationID()的可用性：在可伸缩性等级 3 和 4 中可用。⌋ ( )
 */
TEST(GetCurrentApplicationID)
{
	VAR(ApplicationType, AUTOMATIC) app_id = GetApplicationID();
	P2VAR(struct process_desc, AUTOMATIC, OS_APPL_DATA) pro_desc = current_proc_info();

	/**
	 * [SWS_Os_00798] ⌈ GetCurrentApplicationID()应返回执行当前任务/ISR/hook 的应用程序标识符。 ⌋ ( )
	 * [SWS_Os_00799] ⌈如果没有 OS-Application 正在运行，
	 *  GetCurrentApplicationID()将返回INVALID_OSAPPLICATION 。 ⌋ ( )
	 */
	if (pro_desc->object.app_id >= INVALID_OSAPPLICATION) {
		ASSERT_EQ(app_id, INVALID_OSAPPLICATION);
	} else {
		ASSERT_EQ(app_id, pro_desc->object.app_id);
	}
}

/**
 * [SWS_Os_00537] ⌈ GetApplicationState ()的可用性：在可扩展性等级 3 和 4 中可用。⌋ ( )
 */
TEST(GetApplicationState)
{
	VAR(StatusType, AUTOMATIC) status;
	VAR(ApplicationStateType, AUTOMATIC) Value;
	VAR(ApplicationStateRefType, AUTOMATIC) Value_ref = &Value;

#if defined(EXTENDED_STATUS)
	/**
	 * [SWS_Os_00495] ⌈如果GetApplicationState ()调用中的 <Application>无效，则 GetApplicationState () 应返回E_OS_ID 。 ⌋ ( )
	 */
	status = GetApplicationState(AUTOSAR_NR_APPLICATION, Value_ref);
	ASSERT_EQ(status, E_OS_ID);
#endif

	/**
	 * [SWS_Os_00496] ⌈如果GetApplicationState ()调用中的参数有效， GetApplicationState ()将在<Value>中返回OS-Application<Application>的状态。 ⌋ ( )
	 */
	status = GetApplicationState(0, Value_ref);
	ASSERT_EQ(status, E_OK);
	ASSERT_EQ(Value, autosar_os_app[0].state);

	status = GetApplicationState(1, Value_ref);
	ASSERT_EQ(status, E_OK);
	ASSERT_EQ(Value, autosar_os_app[1].state);
}

/**
 * [SWS_Os_00536] ⌈ TerminateApplication ()的可用性：在可扩展性等级 3 和 4 中可用。⌋ ( )
 * []注意：虽然受信任的操作系统应用程序可以被其他受信
 * 任的操作系统应用程序的任务/中断强行终止，但不建议这
 * 样做。这可能会产生进一步的影响，例如对当前通过
 * CallTrustedFunction()调用属于此类 OS 应用程序的用户的影响。
 */
TEST(TerminateApplication)
{
	VAR(int32_t, AUTOMATIC) i;
	VAR(StatusType, AUTOMATIC) status;
	P2VAR(struct process_desc, AUTOMATIC, OS_APPL_DATA) pro_desc;

#if defined(EXTENDED_STATUS)
	/**
	 * [SWS_Os_00493] ⌈如果TerminateApplication ()调用中的输入参数 <Application>无效，则TerminateApplication () 应返回E_OS_ID。 ⌋ ( )
	 */
	status = TerminateApplication(AUTOSAR_NR_APPLICATION, NO_RESTART);
	ASSERT_EQ(status, E_OS_ID);
	/**
	 * [SWS_Os_00459] ⌈如果TerminateApplication ()调用中的 <RestartOption>无效，则TerminateApplication () 应返回E_OS_VALUE。 ⌋ ( )
	 */
	status = TerminateApplication(0, -11);
	ASSERT_EQ(status, E_OS_VALUE);
	/**
	 * [SWS_Os_00494] ⌈如果	TerminateApplication ()调用中的输入参数 <Application>有效且调用者属于不可信的 OSApplication 且调用者不属于 <Application> TerminateApplication () 应返回E_OS_ACCESS。 ⌋ ( )
	 */
#endif

	/**
	 * [SWS_Os_00507] ⌈如果	TerminateApplication ()	调用中<Application>的状态为APPLICATION_TERMINATED TerminateApplication () 应返回E_OS_STATE。 ⌋ ( )
	 */


	/**
	 * [SWS_Os_00508] ⌈如果在TerminateApplication () 调用中 <Application> 的状态是APPLICATION_RESTARTING并且调用者不属于 <Application> 则TerminateApplication () 应返回E_OS_STATE。 ⌋ ( )
	 */


	/**
	 * [SWS_Os_00548] ⌈如果在TerminateApplication () 的调用中 <Application> 的状态是APPLICATION_RESTARTING并且调用者确实属于 <Application> 并且 <RestartOption> 等于RESTART那么TerminateApplication () 将返回E_OS_STATE 。 ⌋ ( )
	 */

	/**
	 * [SWS_Os_00287] ⌈如果TerminateApplication ()调用中的参数有效且满足上述条件，则TerminateApplication () 将终止 <Application>（即终止所有任务，禁用那些属于 OS 的 ISR 的中断源-应用程序并释放与应用程序相关的所有其他操作系统资源）并且如果 <RestartOption> 等于RESTART则应激活 <Application> 的配置OsRestartTask 。如果没有配置OsRestartTask ，则不会发生重启。如果 <Application> 重新启动，则其状态设置为APPLICATION_RESTARTING否则设置为APPLICATION_TERMINATED 。如果调用者属于 <Application> TerminateApplication () 则不应返回，否则应返回E_OK 。 ⌋ ( )
	 */
	status = TerminateApplication(1, NO_RESTART);
	ASSERT_EQ(status, E_OK);
	for (i = 0; i <OS_NR_TASK; i++) {
		pro_desc = osek_tasks[i].stack;
		if (pro_desc != NULL && pro_desc->object.app_id  == 1) {
			ASSERT_EQ(osek_tasks[i].state, SUSPENDED);
		}
	}
	/**
	 * [SWS_Os_00535] ⌈ TerminateApplication ()的注意事项：
	 *	如果未配置应用程序，则实施应确保此服务不可用。
	 *	受信任的应用程序拥有的任务和中断可以终止任何操作系统
	 * 应用程序。不受信任的应用程序拥有的任务和中断只能终止其拥有
	 * 的操作系统应用程序。 ⌋ ( )
	 */
}
#endif /* defined(AUTOSAR_OS_APPLICATION) */


TEST_SUIT(OsApplication)
{
#if (defined(AUTOSAR_OS_APPLICATION) || defined(AUTOSAR_MULTICORE))
	UTEST_CASE(GetApplicationID);
#endif /* (defined(AUTOSAR_OS_APPLICATION) || defined(AUTOSAR_MULTICORE)) */

#if defined(AUTOSAR_OS_APPLICATION)
	UTEST_CASE(GetCurrentApplicationID);
	UTEST_CASE(GetApplicationState);
	UTEST_CASE(TerminateApplication);
#endif /* defined(AUTOSAR_OS_APPLICATION) */
}

